package com.yunhe.common.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.yunhe.common.metadata.BaseExcelModel;
import com.yunhe.common.util.CollectionUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: DongWenYu
 * @Date: 2021/4/28 10:29
 */
public class ExcelUtils {

    private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class);

    /**
     * 导出
     * @param list
     * @param response
     * @param clazz
     * @return
     */
    public static  void export(List<? extends BaseExcelModel> list, HttpServletResponse response, Class<? extends BaseExcelModel> clazz) {
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
        try {
            String fileName = new String(
                    (new SimpleDateFormat("yyyy-MM-dd").format(new Date())).getBytes(), "UTF-8");
            Sheet sheet2 = new Sheet(2, 3,clazz, "sheet", null);
            writer.write(list, sheet2);
            //response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "utf-8"));
            //response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            out.flush();
            logger.info("导出成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("导出失败");
            //return boUtil;
        } finally {
            writer.finish();
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //return boUtil;
        }
    }

    /**
     * 导出excel
     * @param outputStream 输出流
     * @param dataList     导出的数据
     * @param classT        模板类
     * @param sheetName     sheetName
     * @param cellWriteHandlers    样式处理类
     */
    public static void writeExcelWithModel(OutputStream outputStream, List<? extends Object> dataList, Class<? extends Object> classT, String sheetName, CellWriteHandler... cellWriteHandlers) {

        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 单元格策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 初始化表格样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(outputStream, classT).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy);
        if (null != cellWriteHandlers && cellWriteHandlers.length > 0) {
            for (int i = 0; i < cellWriteHandlers.length; i++) {
                excelWriterSheetBuilder.registerWriteHandler(cellWriteHandlers[i]);
            }
        }
        // 开始导出
        excelWriterSheetBuilder.doWrite(dataList);
    }

    public static<T> void convertAndExport(List<T> sourceList , HttpServletResponse httpServletResponse , Class<? extends BaseExcelModel> clazz ){
        if(CollectionUtil.isNotEmpty(sourceList)){
            List<? extends BaseExcelModel> baseExcelModels = listCopy(sourceList,clazz);
            if(CollectionUtil.isNotEmpty(baseExcelModels)){
                ExcelUtils.export(baseExcelModels ,httpServletResponse, clazz);
            }
        }
    }

    private static <T1, T2> List<T2> listCopy(List<T1> sourceList, Class<T2> clazz) {
        return (List) sourceList.stream().map((source)->{
            Object target;
            try {
                target = clazz.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                throw new RuntimeException();
            }
            BeanUtils.copyProperties(source, target);
            return target;
        }).collect(Collectors.toList());
    }
}
